[−][src]Crate pnet
libpnet
libpnet
provides a cross-platform API for low level networking using Rust.
There are four key components:
- The
packet
module, allowing safe construction and manipulation of packets; - The
pnet_packet
crate, providing infrastructure for the packet module; - The
transport
module, which allows implementation of transport protocols; - The
datalink
module, which allows sending and receiving data link packets directly.
Terminology
The documentation uses the following terms interchangably:
- Layer 2, datalink layer;
- Layer 3, network layer;
- Layer 4, transport layer.
Unless otherwise stated, all interactions with libpnet are in host-byte order - any platform specific variations are handled internally.
Examples
More examples, including a packet logger, and a version of the echo server
written at the transport layer, can be found in the examples/
directory.
Ethernet echo server
This (fairly useless) code implements an Ethernet echo server. Whenever a packet is received on an interface, it echo's the packet back; reversing the source and destination addresses.
extern crate pnet; use pnet::datalink::{self, NetworkInterface}; use pnet::datalink::Channel::Ethernet; use pnet::packet::{Packet, MutablePacket}; use pnet::packet::ethernet::{EthernetPacket, MutableEthernetPacket}; use std::env; // Invoke as echo <interface name> fn main() { let interface_name = env::args().nth(1).unwrap(); let interface_names_match = |iface: &NetworkInterface| iface.name == interface_name; // Find the network interface with the provided name let interfaces = datalink::interfaces(); let interface = interfaces.into_iter() .filter(interface_names_match) .next() .unwrap(); // Create a new channel, dealing with layer 2 packets let (mut tx, mut rx) = match datalink::channel(&interface, Default::default()) { Ok(Ethernet(tx, rx)) => (tx, rx), Ok(_) => panic!("Unhandled channel type"), Err(e) => panic!("An error occurred when creating the datalink channel: {}", e) }; loop { match rx.next() { Ok(packet) => { let packet = EthernetPacket::new(packet).unwrap(); // Constructs a single packet, the same length as the the one received, // using the provided closure. This allows the packet to be constructed // directly in the write buffer, without copying. If copying is not a // problem, you could also use send_to. // // The packet is sent once the closure has finished executing. tx.build_and_send(1, packet.packet().len(), &mut |mut new_packet| { let mut new_packet = MutableEthernetPacket::new(new_packet).unwrap(); // Create a clone of the original packet new_packet.clone_from(&packet); // Switch the source and destination new_packet.set_source(packet.get_destination()); new_packet.set_destination(packet.get_source()); }); }, Err(e) => { // If an error occurs, we can handle it here panic!("An error occurred while reading: {}", e); } } } }
Modules
datalink | Support for sending and receiving data link layer packets. |
packet | Support for packet parsing and manipulation. |
transport | Support for sending and receiving transport layer packets. |
util | Miscellaneous utilities for low-level networking. |